package com.xcm.service.impl;

import java.rmi.ServerException;
import java.text.ParseException;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xcm.cache.RedisCacheDao;
import com.xcm.constant.BusinessConstant;
import com.xcm.constant.CacheConstant;
import com.xcm.constant.DateFormatConstant;
import com.xcm.constant.OperationLogConstant;
import com.xcm.constant.PageConstant;
import com.xcm.dao.DeviceInfoMapper;
import com.xcm.model.TbDeviceInfo;
import com.xcm.model.TbOperationLog;
import com.xcm.model.bo.ClientDeviceBO;
import com.xcm.model.dto.ApkDeviceListDTO;
import com.xcm.model.dto.DeviceInfoListDTO;
import com.xcm.model.vo.SingleDeviceReportVO;
import com.xcm.page.PageInfo;
import com.xcm.service.DeviceInfoService;
import com.xcm.service.OperationLogService;
import com.xcm.util.DateUtils;

/**
 * 终端Service
 */
@Service(value = "deviceInfoService")
public class DeviceInfoServiceImpl implements DeviceInfoService {
	@Autowired
	private DeviceInfoMapper deviceInfoMapper;
	@Autowired
	private RedisCacheDao redisCacheDao;
	@Autowired
	private OperationLogService operationLogService;

	/**
	 * 保存终端
	 *
	 * @param deviceInfo TbDeviceInfo类型对象
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void saveDeviceInfo(TbDeviceInfo deviceInfo) {
		//设置主键
		long currentTimeMillis = System.currentTimeMillis();
		//激活时间
		deviceInfo.setAddTime(currentTimeMillis);
		//最新上报时间
		deviceInfo.setReportTime(currentTimeMillis);
		deviceInfoMapper.saveDeviceInfo(deviceInfo);
	}

	/**
	 * 根据Mac获取终端
	 * getDeviceInfoByMac
	 *
	 * @param deviceMac 终端mac
	 * @return TbDeviceInfo类型对象
	 */
	@Override
	public TbDeviceInfo getDeviceInfoByMac(String deviceMac) {
		return deviceInfoMapper.getDeviceInfoByMac(deviceMac);
	}

	/**
	 * 更新终端
	 * updateDeviceInfo
	 *
	 * @param deviceInfo    TbDeviceInfo类型对象
	 * @param oldDeviceInfo TbDeviceInfo类型对象
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void updateDeviceInfo(TbDeviceInfo deviceInfo, TbDeviceInfo oldDeviceInfo) {
		oldDeviceInfo.setDeviceResolution(deviceInfo.getDeviceResolution());
		oldDeviceInfo.setDeviceSoftVer(deviceInfo.getDeviceSoftVer());
		oldDeviceInfo.setDeviceModel(deviceInfo.getDeviceModel());
		oldDeviceInfo.setDeviceDiskSpace(deviceInfo.getDeviceDiskSpace());
		oldDeviceInfo.setDeviceIp(deviceInfo.getDeviceIp());
		//设置最新上报时间
		long currentTimeMillis = System.currentTimeMillis();
		oldDeviceInfo.setReportTime(currentTimeMillis);
		deviceInfoMapper.updateDeviceInfo(oldDeviceInfo);
	}

	/**
	 * 终端分页列表
	 *
	 * @param groupCode    分组码
	 * @param deviceNum    终端机器码
	 * @param deviceIp     终端IP地址
	 * @param deviceMac    终端MAC
	 * @param deviceStatus 终端状态
	 * @param pageNum      当前页
	 * @param pageSize     每页显示条数
	 * @return Page<DeviceInfoListDTO>
	 */
	@Override
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public Page<DeviceInfoListDTO> listByPage(String groupCode, String deviceNum, String deviceIp, String deviceMac, Integer deviceStatus, Integer pageNum, Integer pageSize) {
		PageHelper.startPage(pageNum, pageSize);
		return deviceInfoMapper.listByPage(groupCode, deviceNum, deviceIp, deviceMac, deviceStatus);
	}

	/**
	 * 修改终端机器码
	 * updateDeviceNum
	 *
	 * @param deviceInfoId 终端id
	 * @param deviceNum    终端机器码
	 * @param deviceMac    终端mac地址
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void updateDeviceNum(Long deviceInfoId, String deviceNum, String deviceMac) {
		deviceInfoMapper.updateDeviceNum(deviceInfoId, deviceNum);
		//设备操作
		ClientDeviceBO clientDeviceBO = (ClientDeviceBO) redisCacheDao.getCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac);
		if (clientDeviceBO == null) {
			clientDeviceBO = new ClientDeviceBO();
		}
		clientDeviceBO.setDeviceNum(deviceNum);
		redisCacheDao.putCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac, clientDeviceBO);
		//保存操作日志
		TbOperationLog operationLog = new TbOperationLog();
		operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_DEVICE);
		operationLog.setOperationContent("修改id=" + deviceInfoId + "的终端机器码为" + deviceNum);
		operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
		operationLog.setOperationTime(System.currentTimeMillis());
		// TODO: 2018/4/9 处理用户ID和IP地址
		//展示设置操作用户名、用户真实姓名、IP为空，用户保存在统一登录系统
		operationLog.setUserName("");
		operationLog.setRealName("");
		operationLog.setOperationIp("");
		operationLogService.saveOperationLog(operationLog);
	}

	/**
	 * 关机
	 *
	 * @param deviceMacs 终端Mac地址
	 * @param groupCode  分组码
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void shutdown(String deviceMacs, String groupCode) {
		StringBuilder operationMsg = new StringBuilder();
		//分组码为空
		if (StringUtils.isBlank(groupCode)) {
			String splitChar = ",";
			for (String deviceMac : deviceMacs.split(splitChar)) {
				//判断是否在线
				Long online = (Long) redisCacheDao.getCache(CacheConstant.CACHE_NAME_DEVICE_ONLINE, deviceMac);
				//设备不在线
				if (online == null) {
					redisCacheDao.deleteByKey(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac);
					continue;
				}
				//设备操作
				ClientDeviceBO clientDeviceBO = (ClientDeviceBO) redisCacheDao.getCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac);
				if (clientDeviceBO == null) {
					clientDeviceBO = new ClientDeviceBO();
				}
				//关机
				clientDeviceBO.setOff(true);
				redisCacheDao.putCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac, clientDeviceBO);
			}
			operationMsg.append("将Mac地址为：" + deviceMacs + "的终端远程关机");
		} else {
			List<String> deviceMacList = null;
			if (groupCode.equals(BusinessConstant.GROUP_CODE_ALL_DEVICE)) {
				deviceMacList = listAllDeviceMac();
				operationMsg.append("将全部终端远程关机");
			} else {
				// TODO: 2018/4/9  //处理分组码
				deviceMacList = deviceInfoMapper.listDeviceMac(groupCode);
				operationMsg.append("将所属分组为：" + groupCode + "的终端远程关机");
			}
			if (CollectionUtils.isNotEmpty(deviceMacList)) {
				for (int i = 0; i < deviceMacList.size(); i++) {
					String deviceMac = deviceMacList.get(i);
					if (StringUtils.isBlank(deviceMac)) {
						continue;
					}
					Long cache = (Long) redisCacheDao.getCache(CacheConstant.CACHE_NAME_DEVICE_ONLINE, deviceMac);
					//设备不在线
					if (cache == null) {
						redisCacheDao.deleteByKey(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac);
					} else {
						//设备在线
						ClientDeviceBO clientDeviceBO = (ClientDeviceBO) redisCacheDao.getCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac);
						if (clientDeviceBO == null) {
							clientDeviceBO = new ClientDeviceBO();
						}
						//设置关机
						clientDeviceBO.setOff(true);
						redisCacheDao.putCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac, clientDeviceBO);
					}
				}
			}

		}
		//保存操作日志
		TbOperationLog operationLog = new TbOperationLog();
		operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_DEVICE);
		operationLog.setOperationContent(operationMsg.toString());
		operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
		operationLog.setOperationTime(System.currentTimeMillis());
		// TODO: 2018/4/9 处理用户ID和IP地址
		//展示设置操作用户名、用户真实姓名、IP为空，用户保存在统一登录系统
		operationLog.setUserName("");
		operationLog.setRealName("");
		operationLog.setOperationIp("");
		operationLogService.saveOperationLog(operationLog);
	}

	/**
	 * 获取所有终端Mac地址
	 *
	 * @return List<String>
	 */
	@Override
	public List<String> listAllDeviceMac() {
		return deviceInfoMapper.listAllDeviceMac();
	}

	/**
	 * 重启
	 *
	 * @param deviceMacs 终端Mac地址
	 * @param groupCode  分组码
	 */
	@Override
	public void restart(String deviceMacs, String groupCode) {
		StringBuilder operationMsg = new StringBuilder();
		//分组码为空
		if (StringUtils.isBlank(groupCode)) {
			String splitChar = ",";
			for (String deviceMac : deviceMacs.split(splitChar)) {
				//判断是否在线
				Long online = (Long) redisCacheDao.getCache(CacheConstant.CACHE_NAME_DEVICE_ONLINE, deviceMac);
				//设备不在线
				if (online == null) {
					redisCacheDao.deleteByKey(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac);
					continue;
				}
				//设备操作
				ClientDeviceBO clientDeviceBO = (ClientDeviceBO) redisCacheDao.getCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac);
				if (clientDeviceBO == null) {
					clientDeviceBO = new ClientDeviceBO();
				}
				//关机
				clientDeviceBO.setRestart(true);
				redisCacheDao.putCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac, clientDeviceBO);
			}
			operationMsg.append("将Mac地址为：" + deviceMacs + "的终端重启");
		} else {
			List<String> deviceMacList = null;
			if (groupCode.equals(BusinessConstant.GROUP_CODE_ALL_DEVICE)) {
				deviceMacList = listAllDeviceMac();
				operationMsg.append("将全部终端重启");
			} else {
				// TODO: 2018/4/9  //处理分组码
				deviceMacList = deviceInfoMapper.listDeviceMac(groupCode);
				operationMsg.append("将所属分组为：" + groupCode + "的终端重启");
			}
			if (CollectionUtils.isNotEmpty(deviceMacList)) {
				for (int i = 0; i < deviceMacList.size(); i++) {
					String deviceMac = deviceMacList.get(i);
					if (StringUtils.isBlank(deviceMac)) {
						continue;
					}
					Long cache = (Long) redisCacheDao.getCache(CacheConstant.CACHE_NAME_DEVICE_ONLINE, deviceMac);
					//设备不在线
					if (cache == null) {
						redisCacheDao.deleteByKey(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac);
					} else {
						//设备在线
						ClientDeviceBO clientDeviceBO = (ClientDeviceBO) redisCacheDao.getCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac);
						if (clientDeviceBO == null) {
							clientDeviceBO = new ClientDeviceBO();
						}
						//设置关机
						clientDeviceBO.setRestart(true);
						redisCacheDao.putCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, deviceMac, clientDeviceBO);
					}
				}
			}
		}
		//保存操作日志
		TbOperationLog operationLog = new TbOperationLog();
		operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_DEVICE);
		operationLog.setOperationContent(operationMsg.toString());
		operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
		operationLog.setOperationTime(System.currentTimeMillis());
		// TODO: 2018/4/9 处理用户ID和IP地址
		//展示设置操作用户名、用户真实姓名、IP为空，用户保存在统一登录系统
		operationLog.setUserName("");
		operationLog.setRealName("");
		operationLog.setOperationIp("");
		operationLogService.saveOperationLog(operationLog);
	}

	/**
	 * 指定终端升级
	 *
	 * @param deviceInfoId    终端ID
	 * @param deviceUpgradeId 终端升级ID
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void updateDeviceUpdate(Long deviceInfoId, Long deviceUpgradeId) {
		TbDeviceInfo deviceInfo = getDeviceInfoById(deviceInfoId);
		if (deviceInfo != null) {
			deviceInfo.setUpgradeId(deviceUpgradeId);
			deviceInfo.setUpgradeTime(System.currentTimeMillis());
			deviceInfoMapper.updateDeviceInfo(deviceInfo);
			//保存操作日志
			TbOperationLog operationLog = new TbOperationLog();
			operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_DEVICE);
			operationLog.setOperationContent("设置id=" + deviceInfoId + "的终端使用id=" + deviceUpgradeId + "的apk进行升级!");
			operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
			operationLog.setOperationTime(System.currentTimeMillis());
			// TODO: 2018/4/9 处理用户ID和IP地址
			//展示设置操作用户名、用户真实姓名、IP为空，用户保存在统一登录系统
			operationLog.setUserName("");
			operationLog.setRealName("");
			operationLog.setOperationIp("");
			operationLogService.saveOperationLog(operationLog);
		}
	}

	/**
	 * 通过终端ID获取终端
	 *
	 * @param deviceInfoId 终端id
	 * @return TbDeviceInfo
	 */
	@Override
	public TbDeviceInfo getDeviceInfoById(Long deviceInfoId) {
		return deviceInfoMapper.getDeviceInfoById(deviceInfoId);
	}

	/**
	 * 设置定时开关机
	 *
	 * @param deviceMacs 终端Mac地址
	 * @param groupCode  分组码
	 * @param useTimer   (1:启用 0:关闭)
	 * @param bootTime   开机时间
	 * @param offTime    关机时间
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void updateDeviceBootOffTime(String deviceMacs, String groupCode, Integer useTimer, Long bootTime, Long offTime) {
		StringBuilder operationMsg = new StringBuilder();
		StringBuilder isUse = new StringBuilder();
		if (useTimer == 1) {
			isUse.append("启用");
		} else {
			isUse.append("不启用");
		}
		if (StringUtils.isBlank(groupCode)) {
			//如果分组码为空，更新所有终端的开关机时间
			String[] deviceMacArray = deviceMacs.split(",");
			if (deviceMacArray != null && deviceMacArray.length > 0) {
				deviceInfoMapper.updateDeviceBootOffTimeByDeviceMacArray(useTimer, bootTime, offTime, deviceMacArray);
			}
			operationMsg.append("设置Mac地址为：" + deviceMacs + "的终端" + isUse + "定时开关机，开关机时间：" + bootTime + " - " + offTime);
		} else {
			//更新所有终端的开关机时间
			if (BusinessConstant.GROUP_CODE_ALL_DEVICE.equals(groupCode)) {
				deviceInfoMapper.updateAllDeviceBootOffTime(useTimer, bootTime, offTime);
				operationMsg.append("设置所有终端" + isUse + "定时开关机，开关机时间：" + bootTime + " - " + offTime);
			} else {
				//通过分组码更新终端开关机（机器码：device_num前缀与分组码一致）
				// TODO: 2018/4/10 处理分组码的问题
				deviceInfoMapper.updateDeviceBootOffTimeByGroupCode(useTimer, bootTime, offTime, groupCode);
				operationMsg.append("设置属于分组码为：" + groupCode + "的终端" + isUse + "定时开关机，开关机时间：" + bootTime + " - " + offTime);
			}
		}
		//保存操作日志
		TbOperationLog operationLog = new TbOperationLog();
		operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_DEVICE);
		operationLog.setOperationContent(operationMsg.toString());
		operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
		operationLog.setOperationTime(System.currentTimeMillis());
		// TODO: 2018/4/9 处理用户ID和IP地址
		//展示设置操作用户名、用户真实姓名、IP为空，用户保存在统一登录系统
		operationLog.setUserName("");
		operationLog.setRealName("");
		operationLog.setOperationIp("");
		operationLogService.saveOperationLog(operationLog);
	}

	/**
	 * 设置音量
	 *
	 * @param deviceMacs   终端Macs地址
	 * @param groupCode    分组码
	 * @param deviceVolume 音量
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void updateDeviceVolume(String deviceMacs, String groupCode, Integer deviceVolume) {
		StringBuilder operationMsg = new StringBuilder();
		//如果分组码为空，更新所有设备的音量
		if (StringUtils.isBlank(groupCode)) {
			String[] macArray = deviceMacs.split(",");
			if (macArray != null && macArray.length > 0) {
				deviceInfoMapper.updateDeviceVolumeByDeviceMacArray(deviceVolume, macArray);
			}
			operationMsg.append("设置Mac地址为：" + deviceMacs + "的终端音量为：" + deviceVolume);
		} else {
			//更新所有设备的音量
			if (BusinessConstant.GROUP_CODE_ALL_DEVICE.equals(groupCode)) {
				deviceInfoMapper.updateAllDeviceVolume(deviceVolume);
				operationMsg.append("设置所有终端的音量为：" + deviceVolume);
			} else {
				//通过分组码更新终端音量（机器码：device_num前缀与分组码一致）
				// TODO: 2018/4/10 处理分组码管理的逻辑
				deviceInfoMapper.updateDeviceVolumeByGroupCode(deviceVolume, groupCode);
				operationMsg.append("设置属于分组码为：" + groupCode + "的终端音量为：" + deviceVolume);
			}
		}
		//保存操作日志
		TbOperationLog operationLog = new TbOperationLog();
		operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_DEVICE);
		operationLog.setOperationContent(operationMsg.toString());
		operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
		operationLog.setOperationTime(System.currentTimeMillis());
		// TODO: 2018/4/9 处理用户ID和IP地址
		//展示设置操作用户名、用户真实姓名、IP为空，用户保存在统一登录系统
		operationLog.setUserName("");
		operationLog.setRealName("");
		operationLog.setOperationIp("");
		operationLogService.saveOperationLog(operationLog);
	}

	/**
	 * 通过终端MAC设置机器码
	 *
	 * @param deviceMac 终端mac地址
	 * @param deviceNum 机器码
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void updateDeviceNumByDeviceMac(String deviceMac, String deviceNum) {
		deviceInfoMapper.updateDeviceNumByDeviceMac(deviceMac, deviceNum);
	}

	/**
	 * 通过终端MAC设置音量
	 *
	 * @param deviceMac    终端Macs地址
	 * @param deviceVolume 音量
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void updateDeviceVolumeByDeviceMac(String deviceMac, Integer deviceVolume) {
		deviceInfoMapper.updateDeviceVolumeByDeviceMac(deviceMac, deviceVolume);
	}

	/**
	 * 通过mac地址设置定时开关机
	 *
	 * @param deviceMac 终端Mac地址
	 * @param useTimer  (1:启用 0:关闭)
	 * @param bootTime  开机时间
	 * @param offTime   关机时间
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void updateDeviceBootOffTimeByMac(String deviceMac, Integer useTimer, Long bootTime, Long offTime) {
		deviceInfoMapper.updateDeviceBootOffTimeByDeviceMacArray(useTimer, bootTime, offTime, new String[]{deviceMac});
	}

	/**
	 * 获取分组码所属的终端Mac地址
	 *
	 * @param groupCode 分组码
	 * @return List<String>
	 */
	@Override
	public List<String> listDeviceMac(String groupCode) {

		return deviceInfoMapper.listDeviceMac(groupCode);
	}

	/**
	 * 上传日志（云端发指令通知终端上传日志）
	 *
	 * @param mac mac地址
	 */
	@Override
	public void uploadLog(String mac) {
		//从缓存中获取
		ClientDeviceBO clientDeviceBO = (ClientDeviceBO) redisCacheDao.getCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, mac);
		if (clientDeviceBO == null) {
			clientDeviceBO = new ClientDeviceBO();
		}
		//设置上传日志为true
		clientDeviceBO.setLog(true);
		//放入缓存中
		redisCacheDao.putCache(CacheConstant.CACHE_NAME_DEVICE_OPTION, mac, clientDeviceBO);

		//保存操作日志
		TbOperationLog operationLog = new TbOperationLog();
		operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_DEVICE);
		operationLog.setOperationContent("上传Mac地址为：" + mac + "的终端日志");
		operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
		operationLog.setOperationTime(System.currentTimeMillis());
		// TODO: 2018/4/9 处理用户ID和IP地址
		//展示设置操作用户名、用户真实姓名、IP为空，用户保存在统一登录系统
		operationLog.setUserName("");
		operationLog.setRealName("");
		operationLog.setOperationIp("");
		operationLogService.saveOperationLog(operationLog);
	}

	/**
	 * 获取在线终端数
	 *
	 * @return Long
	 */
	@Override
	public Long getOnlineDeviceInfoCount() {
		return deviceInfoMapper.getDeviceInfoCountByDeviceStatus(BusinessConstant.DEVICE_INFO_STATUS_ON_LINE);
	}

	/**
	 * 获取离线终端数
	 *
	 * @return Long
	 */
	@Override
	public Long getOfflineDeviceInfoCount() {
		return deviceInfoMapper.getDeviceInfoCountByDeviceStatus(BusinessConstant.DEVICE_INFO_STATUS_OFF_LINE);
	}

	/**
	 * 通过机器编码获取在线终端数量
	 *
	 * @param deviceNum
	 * @return
	 */
	@Override
	public Long getOnlineDeviceInfoCountbyDeviceNum(String deviceNum) {
		return deviceInfoMapper.getDeviceInfoCountByDeviceStatusAndDeviceNum(deviceNum, BusinessConstant.DEVICE_INFO_STATUS_ON_LINE);
	}

	/**
	 * 通过机器编码获取离线终端数量
	 *
	 * @param deviceNum
	 * @return
	 */
	@Override
	public Long getOfflineDeviceInfoCountbyDeviceNum(String deviceNum) {
		return deviceInfoMapper.getDeviceInfoCountByDeviceStatusAndDeviceNum(deviceNum, BusinessConstant.DEVICE_INFO_STATUS_OFF_LINE);
	}

	/**
	 * 通过IP地址获取在线终端数量
	 *
	 * @param deviceIp
	 * @return
	 */
	@Override
	public Long getOnlineDeviceInfoCountbyDeviceIp(String deviceIp) {
		return deviceInfoMapper.getDeviceInfoCountByDeviceStatusAndDeviceIP(deviceIp, BusinessConstant.DEVICE_INFO_STATUS_ON_LINE);
	}

	/**
	 * 通过IP地址获取离线终端数量
	 *
	 * @param deviceIp
	 * @return
	 */
	@Override
	public Long getOfflineDeviceInfoCountbyDeviceIp(String deviceIp) {
		return deviceInfoMapper.getDeviceInfoCountByDeviceStatusAndDeviceIP(deviceIp, BusinessConstant.DEVICE_INFO_STATUS_OFF_LINE);
	}

	/**
	 * 通过MAC地址获取在线终端数量
	 *
	 * @param deviceMac
	 * @return
	 */
	@Override
	public Long getOnlineDeviceInfoCountbyDeviceMac(String deviceMac) {
		return deviceInfoMapper.getDeviceInfoCountByDeviceStatusAndDeviceMac(deviceMac, BusinessConstant.DEVICE_INFO_STATUS_ON_LINE);
	}

	/**
	 * 通过MAC地址获取离线终端数量
	 *
	 * @param deviceMac
	 * @return
	 */
	@Override
	public Long getOfflineDeviceInfoCountbyDeviceMac(String deviceMac) {
		return deviceInfoMapper.getDeviceInfoCountByDeviceStatusAndDeviceMac(deviceMac, BusinessConstant.DEVICE_INFO_STATUS_OFF_LINE);
	}

	/**
	 * 通过分组编码获取在线终端数量
	 *
	 * @param groupCode
	 * @return
	 */
	@Override
	public Long getOnlineDeviceInfoCountbyGroupCode(String groupCode) {
		return deviceInfoMapper.getDeviceInfoCountByDeviceStatusAndGroupCode(groupCode, BusinessConstant.DEVICE_INFO_STATUS_ON_LINE);
	}

	/**
	 * 通过分组编码获取离线终端数量
	 *
	 * @param groupCode
	 * @return
	 */
	@Override
	public Long getOfflineDeviceInfoCountbyGroupCode(String groupCode) {
		return deviceInfoMapper.getDeviceInfoCountByDeviceStatusAndGroupCode(groupCode, BusinessConstant.DEVICE_INFO_STATUS_OFF_LINE);
	}


	/**
	 * 获取终端信息
	 *
	 * @param mipsVersion  mips版本
	 * @param deviceStatus 终端状态
	 * @param model        机型
	 * @param province     省
	 * @param city         市
	 * @param county       区
	 * @param groupCode    分组码
	 * @param pageNum      当期页
	 * @param pageSize     每页条数
	 * @return PageInfo<ApkDeviceListDTO>
	 */
	@Override
	public PageInfo<ApkDeviceListDTO> listApkDeviceByPage(String mipsVersion, Integer deviceStatus, String model, String province, String city, String county, String groupCode, Integer pageNum, Integer pageSize) {
		if (pageNum == null) {
			pageNum = PageConstant.DEFAULT_PAGE_NUM;
		}
		if (pageSize == null) {
			pageSize = PageConstant.DEFAULT_PAGE_SIZE;
		}
		PageHelper.startPage(pageNum, pageSize);
		Page<ApkDeviceListDTO> page = deviceInfoMapper.listApkDeviceByPage(mipsVersion, deviceStatus, model, province, city, county, groupCode);
		PageInfo<ApkDeviceListDTO> pageInfo = new PageInfo<>();
		if (page == null) {
			return pageInfo;
		}
		pageInfo.setList(page.getResult());
		pageInfo.setTotal(page.getTotal());
		pageInfo.setPageNum(page.getPageNum());
		pageInfo.setPageSize(page.getPageSize());
		return pageInfo;
	}

	/**
	 * 获取在线终端数
	 *
	 * @param mipsVersion mips版本
	 * @param model       机型
	 * @param province    省
	 * @param city        市
	 * @param county      区
	 * @param groupCode   分组码
	 * @return Long
	 */
	@Override
	public Long getApkDeviceOnlineCount(String mipsVersion, String model, String province, String city, String county, String groupCode) {
		return deviceInfoMapper.getDeviceInfoCount(BusinessConstant.DEVICE_INFO_STATUS_ON_LINE, mipsVersion, model, province, city, county, groupCode);
	}

	/**
	 * 获取离线终端数
	 *
	 * @param mipsVersion mips版本
	 * @param model       机型
	 * @param province    省
	 * @param city        市
	 * @param county      区
	 * @param groupCode   分组码
	 * @return Long
	 */
	@Override
	public Long getApkDeviceOfflineCount(String mipsVersion, String model, String province, String city, String county, String groupCode) {
		return deviceInfoMapper.getDeviceInfoCount(BusinessConstant.DEVICE_INFO_STATUS_OFF_LINE, mipsVersion, model, province, city, county, groupCode);
	}

	/**
	 * 通过终端升级ids更新软件升级ID
	 * @param deviceInfoIds 终端ID字符串集合("1,2,3,4")
	 * @param softwareUpgradeId   软件升级ID
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void updateSoftwareUpgradeIdByDeviceInfoIds(String deviceInfoIds, Long softwareUpgradeId) throws ServerException {
		if (StringUtils.isBlank(deviceInfoIds)) {
			throw new ServerException("终端ID集不能为空");
		}
		if (softwareUpgradeId == null) {
			throw new ServerException("软件升级ID不能为空");
		}
		deviceInfoMapper.updateSoftwareUpgradeIdByDeviceInfoIds(deviceInfoIds, softwareUpgradeId);
	}
	
	/**
	 * 获取单个终端的报表信息-分页
	 * @param startTime 时间点-开始
	 * @param endTime 时间点-结束
	 * @param deviceNum 机器码
	 * @param mac mac地址
	 * @param pageNum 
	 * @param pageSize
	 * @return
	 */
	@Override
	public Page<SingleDeviceReportVO> listSingleDeviceReport(String startTime, String endTime, String deviceNum,
			String mac, Integer pageNum, Integer pageSize) {
		if (pageNum == null) {
			pageNum = PageConstant.DEFAULT_PAGE_NUM;
		}
		if (pageSize == null) {
			pageSize = PageConstant.DEFAULT_PAGE_SIZE;
		}
		PageHelper.startPage(pageNum, pageSize);
		Long start = null;
		Long end = null;
		try {
			if (StringUtils.isNotBlank(startTime)) {
				start = DateUtils.stringTimeToLongTimeStamp(startTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
			if (StringUtils.isNotBlank(endTime)) {
				end = DateUtils.stringTimeToLongTimeStamp(endTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return deviceInfoMapper.listSingleDeviceReport(start, end, deviceNum, mac);
	}
	
	/**
	 * 获取单个终端的报表信息-不分页
	 * @param startTime 时间点-开始
	 * @param endTime 时间点-结束
	 * @param deviceNum 机器码
	 * @param mac mac地址
	 * @return
	 */
	@Override
	public List<SingleDeviceReportVO> listExportSingleDeviceDetailReport(String startTime, String endTime,String deviceNum, String mac) {
		Long start = null;
		Long end = null;
		try {
			if (StringUtils.isNotBlank(startTime)) {
				start = DateUtils.stringTimeToLongTimeStamp(startTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
			if (StringUtils.isNotBlank(endTime)) {
				end = DateUtils.stringTimeToLongTimeStamp(endTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return deviceInfoMapper.listSingleDeviceReport(start, end, deviceNum, mac);
	}

}
